from typing import List, Union

from fastapi import APIRouter, Path, Request
from pydantic import parse_obj_as
from tortoise.exceptions import OperationalError
from tortoise.transactions import in_transaction

from ..models import TagModel
from ..schemas import (TagInfo, TagStatus, CreateTag, UpdateTag,FailResp,
                       MultiResp, SingleResp, SuccessResp, )

router = APIRouter(prefix='/tags', tags=['分类管理'])


@router.get("/options", summary="所有分类", response_model=MultiResp[TagInfo])
async def all_tags_options():
    #查询所有激活状态的分类
    all_tags = await TagModel.filter(status=1).order_by('id')
    data = parse_obj_as(List[TagInfo], all_tags)
    return MultiResp[TagInfo](data=data)



@router.post("", summary="分类添加")
async def create_tags(req: Request, post: CreateTag):
    if await TagModel.filter(name=post.name).exists():
        return FailResp(code=10101, msg='当前分类已创建')
    await TagModel.create(**post.dict())
    return SuccessResp(data="创建成功!")


@router.put("/status", summary="分类状态")
async def set_tag_status(req: Request, post: TagStatus):
    tag = await TagModel.get_or_none(pk=post.id)
    if tag is None:
        return FailResp(code=30501, msg=f"分类不存在")
    tag.status = post.status
    await tag.save()
    msg = f"分类 [ID={tag.pk}] 已"
    msg += "停用" if post.status==9 else "启用"
    return SuccessResp(data=msg)


@router.delete("/{tid}", summary="删除分类")
async def tag_delete(req: Request, tid: int = Path(..., gt=0)):
    tag = await TagModel.get_or_none(pk=tid)
    if tag is None:
        return FailResp(code=30201, msg="分类不存在!")
    #软删除,标记状态为9
    await TagModel.filter(pk=tid).update(status=9)
    return SuccessResp(data="删除成功!")


@router.put("/{tid}", summary="修改分类")
async def tag_update(req: Request, post: UpdateTag, tid: int = Path(..., gt=0)):
    tag = await TagModel.get_or_none(pk=tid)
    if tag is None:
        return FailResp(code=30201, msg="分类不存在!")
    if tag.name != post.name:
        check_tag_name = await TagModel.get_or_none(name=post.name)
        if check_tag_name:
            return FailResp(code=20502, msg=f"分类名{post.name}已存在")
    # 使用事务，保证数据完整
    try:
        async with in_transaction():
            # 更新分类
            update_data = post.dict(exclude_unset=True, exclude_none=True)
            await tag.update_from_dict(update_data)
            await tag.save()
    except OperationalError:
        return FailResp(code=30301, msg="更新失败!")
    return SuccessResp(data="更新成功!")